package com.qyy.springblog.utils;

import com.qyy.springblog.constants.Constant;
import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SignatureException;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.SecretKey;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class JWTUtils {

    //过期时间:设置为一小时后过期
    private final static long EXPIRATION_DATE = 24 * 60 * 60 * 1000;
    private final static String secretString = "sqmbcvcBPjfvJ4ilRLqbGmHeUaCEwdpv10jSRbCNtH4=";
    private final static Key key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secretString));//生成key

    /**
     * 生成token令牌
     */
    public static String gentToken(Map<String,Object> claim){
        return Jwts.builder()//创建 JWT 构建器实例，使用 JJWT 库提供的 API。
                .setClaims(claim) //设置头部和荷负载
                .setExpiration(new Date(System.currentTimeMillis()+EXPIRATION_DATE))
                //设置 JWT 的过期时间，通过当前时间（System.currentTimeMillis()）
                // 加上预定义的常量EXPIRATION_DATE（毫秒数）计算得出。
                .signWith(key) //设置签名，使用指定的密钥key对 JWT 进行签名，确保令牌的完整性和真实性
                .compact();//将 JWT 的头部、负载和签名组合并编码为标准的 JWT 字符串格式。
    }

    /**
     * 随机生成Key.(标签)
     * 由于我们已经生成了因此不需要这个代码了
     */
//    public void genKey(){
//        SecretKey secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);
//        String encode = Encoders.BASE64.encode(secretKey.getEncoded());
//        System.out.println(encode);
//    }

    /**
     * 解析Token
     */
    public static Claims parseToken(String token){

        Claims body = null;
        JwtParser build = Jwts.parserBuilder().setSigningKey(key).build();
        try {
            body = build.parseClaimsJws(token).getBody();
        } catch (ExpiredJwtException e) {
            log.info("token过期，校验失败,token:{}",token);
        } catch (Exception e) {
            log.info("token校验失败,token:{}",token);
        }
        return body;
    }
    public static boolean checkToken(String token){
        Claims body = parseToken(token);
        if(body == null){
            return false;
        }
        return true;
    }

    public static Integer getUserIdFromToken(String token){
        Claims body = parseToken(token);
        if(body != null){
            return (Integer) body.get(Constant.USER_CLAIM_Id);

        }
        return null;
    }
}
